#! /usr/bin/python
# -*- coding: utf-8 -*-

from google.appengine.api import urlfetch
import time
import conf
import utils
import urllib
import types
from xml.dom.minidom import parseString

class rest:
    def __init__(self, sessionKey, sessionSecret=''):
        self.restServer = 'http://api.' + conf.xiaoneiDomain + '/restserver.do'
        self.apiKey = conf.api_key
        self.sessionKey = sessionKey
        if sessionSecret:
            self.secret = sessionSecret
        else:
            self.secret = conf.app_secret
    
    def sendRestRequest(self, paramsDict):
        formData = urllib.urlencode(paramsDict)
        result = urlfetch.fetch(url=self.restServer,
            payload=formData,
            method=urlfetch.POST,
            headers={'Content-Type': 'application/x-www-form-urlencoded'})
        if result.status_code == 200:
            return result.content
        else:
            return 'error response code: ' + str(result.status_code)

    #return JSON: {'errCode':xxx, 'errMsg':'xxx','resultData':xxx,'errData':{'error_code':xxx,'error_msg':'xxx'}}
    def usersGetInfo(self, uidsArray, fieldsArray):
        uidsStr = self.arrayToString(uidsArray)
        fieldsStr = self.arrayToString(fieldsArray)
        paramsDict = {
            'api_key': self.apiKey,
            'method': 'users.getInfo',
            'call_id': str(time.time()),
            'v': '1.0',
            'uids': uidsStr,
            'fields': fieldsStr,
            'format': 'XML',
            'session_key': self.sessionKey
        }
        paramsDict['sig'] = utils.signature(paramsDict, self.secret)
        responseText = self.sendRestRequest(paramsDict)
        #responseText examples:
        #<?xml version="1.0" encoding="UTF-8"?><users_getInfo_response xmlns="http://api.xiaonei.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://api.xiaonei.com/1.0/ http://api.xiaonei.com/1.0/xiaonei.xsd" list="true"><user><uid>240650143</uid><name>Tielei</name><tinyurl>http://hdn211.xnimg.cn/photos/hdn211/20090330/21/35/tiny_WahI_49626j204238.jpg</tinyurl><headurl>http://hdn511.xnimg.cn/photos/hdn511/20090330/21/30/head_9Ncx_314828j204236.jpg</headurl><mainurl>http://hdn511.xnimg.cn/photos/hdn511/20090330/21/30/main_UkbD_314828j204236.jpg</mainurl><tinyurl_with_logo>http://xnimg.connect.renren.com/safeImage.do?url=http%3A%2F%2Fhdn211.xnimg.cn%2Fphotos%2Fhdn211%2F20090330%2F21%2F35%2Ftiny_WahI_49626j204238.jpg</tinyurl_with_logo><headurl_with_logo>http://xnimg.connect.renren.com/safeImage.do?url=http%3A%2F%2Fhdn511.xnimg.cn%2Fphotos%2Fhdn511%2F20090330%2F21%2F30%2Fhead_9Ncx_314828j204236.jpg</headurl_with_logo><mainurl_with_logo>http://xnimg.connect.renren.com/safeImage.do?url=http%3A%2F%2Fhdn511.xnimg.cn%2Fphotos%2Fhdn511%2F20090330%2F21%2F30%2Fmain_UkbD_314828j204236.jpg</mainurl_with_logo></user><user><uid>255357732</uid><name>Tielei001</name><tinyurl>http://head.xiaonei.com/photos/0/0/men_tiny.gif</tinyurl><headurl>http://head.xiaonei.com/photos/0/0/men_head.gif</headurl><mainurl>http://head.xiaonei.com/photos/0/0/men_main.gif</mainurl><tinyurl_with_logo>http://xnimg.connect.renren.com/safeImage.do?url=http%3A%2F%2Fhead.xiaonei.com%2Fphotos%2F0%2F0%2Fmen_tiny.gif</tinyurl_with_logo><headurl_with_logo>http://xnimg.connect.renren.com/safeImage.do?url=http%3A%2F%2Fhead.xiaonei.com%2Fphotos%2F0%2F0%2Fmen_head.gif</headurl_with_logo><mainurl_with_logo>http://xnimg.connect.renren.com/safeImage.do?url=http%3A%2F%2Fhead.xiaonei.com%2Fphotos%2F0%2F0%2Fmen_main.gif</mainurl_with_logo></user></users_getInfo_response>
        #<?xml version="1.0" encoding="UTF-8"?><error_response><error_code>452</error_code><error_msg>Session kek valid</error_msg><request_args><arg><key>method</key><value>xiaonei.users.getInfo</value></arg><arg><key>uids</key><value>240650143,255357732</value></arg><arg><key>sig</key><value>d2adff26687c9cbde4df514826892fec</value></arg><arg><key>session_key</key><value>jfdkfjk454k</value></arg><arg><key>v</key><value>1.0</value></arg><arg><key>format</key><value>XML</value></arg><arg><key>fields</key><value>name,tinyurl_with_logo,headurl_with_logo,mainurl_with_logo</value></arg><arg><key>api_key</key><value>afb63a32697542818b1a7acba2562b9e</value></arg><arg><key>call_id</key><value>1249948564.52</value></arg></request_args></error_response>
        responseJson = {
            'errCode': -1,
            'errMsg': responseText,
            'resultData': None,
            'errorData': None
        }
        #parse responseText to responseJson
        try:
            #print 'responseText=',responseText
            dom1 = parseString(responseText)
            #print 'dom1=', dom1
            errorNodes = dom1.getElementsByTagName('error_response')
            if errorNodes:
                #error occurs
                errorNode = errorNodes[0]
                errCodeNode = errorNode.getElementsByTagName('error_code')[0]
                responseJson['errCode'] = errCodeNode.childNodes[0].data
                errMsgNode = errorNode.getElementsByTagName('error_msg')[0]
                responseJson['errMsg'] = errMsgNode.childNodes[0].data
                responseJson['errorData'] = {
                    'error_code': responseJson['errCode'],
                    'error_msg': responseJson['errMsg']
                }
            else:
                #calculate resultData
                userNodes = dom1.getElementsByTagName('user')
                resultUserList = []
                for userNode in userNodes:
                    resultUser = {}
                    for field in fieldsArray:
                        fieldNode = userNode.getElementsByTagName(field)[0]
                        resultUser[field] = fieldNode.childNodes[0].data
                    resultUserList.append(resultUser)
                responseJson['errCode'] = 0
                responseJson['errMsg'] = ''
                responseJson['resultData'] = resultUserList
        except Exception:
            None
        except BaseException:
            None
        
        #try:
        #    jsonData = json.loads(responseText)
        #    if type(jsonData) is types.ListType:
        #        responseJson['resultData'] = jsonData
        #    else:
        #        errResultCode = jsonData.get('error_code')
        #        if errResultCode:
        #            responseJson['errData'] = jsonData
        #            responseJson['errCode'] = errResultCode
        #            responseJson['errMsg'] = jsonData.get('error_msg')
        #except ValueError:
        #    responseJson['errCode'] = -1
        #    responseJson['errMsg'] = responseText
        #return responseJson
        #nameNode = dom1.getElementsByTagName('name')[0]
        #nameTextNode = nameNode.childNodes[0]
        #return nameTextNode.data
        return responseJson
    
    #specail conversion function (from array to string) for Xiaonei Rest
    def arrayToString(self, array):
        if not array:
            #array None or zero length
            return ''
        arrayStr = str(array[0])
        i = 1
        while i < len(array):
            arrayStr += ',' + str(array[i])
            i += 1
        return arrayStr